home *** CD-ROM | disk | FTP | other *** search
/ Language/OS - Multiplatform Resource Library / LANGUAGE OS.iso / oper_sys / oasis / oasis1-1.lha / oasis-1.1 / gen.y < prev    next >
Text File  |  1992-05-01  |  45KB  |  740 lines

  1. /*==========================================================================*
  2.     Oasis Alpha Version 1.1               (C) Copyright 1992 Fah-Chun Cheong
  3.     Revised: 5/1/92 by: fcc@eecs.umich.edu    and The University of Michigan
  4.     ------------------------------------------------------------------------
  5.     Permission to use, copy, modify, distribute, sell and resell Oasis Alpha
  6.     software and its documentation for any purpose and without fee is hereby
  7.     granted, provided that the authorship be appropriately credited and
  8.     acknowledged, and that the above copyright notice appear in all copies
  9.     and both the copyright notice and this permission notice appear in
  10.     supporting documentation. The author makes no representations about the
  11.     suitability of this software for any purpose. It is provided "as is"
  12.     without express or implied warranty. Oasis Alpha is free, caveat emptor!
  13.     ------------------------------------------------------------------------
  14.     To request Oasis Alpha source code:   oasis-alpha-request@eecs.umich.edu
  15.     To enroll in the mailing list:        oasis-alpha-request@eecs.umich.edu
  16.     To send bug reports:                  oasis-alpha-bugs@eecs.umich.edu
  17.     To discuss openly all matters Oasis:  oasis-alpha@eecs.umich.edu
  18.  *==========================================================================*/
  19. %{
  20. #include                "gener.h"
  21.  
  22. #define PNO             5000
  23.  
  24. char                   *buf;
  25. Program                *ptab;
  26. int                     pno = 0;
  27. int                     pix = 0;
  28.  
  29. static  int             fail, next, skip, labno = 0;
  30. static  int             a;
  31. static  int             b;
  32. static  int             n;
  33. static  int             k;
  34. static  int             s;
  35. static  char            lab[1024];
  36. static  char           *pname;
  37. static  int             failed;
  38. %}
  39. %union {
  40.         int     i;
  41.         double  f;
  42.         char    c;
  43.         char   *s;
  44. }
  45. %token          DOT DO ISA IF THEN RETURN
  46. %token          EQ NE LT LE GT GE
  47. %token          C I F O A Y L
  48. %token          NIL TRUE FAIL WAIT POST
  49. %token  <s>     ID CID
  50. %token  <i>     G VID MID GID LID
  51. %token  <i>     ATINET
  52. %token  <i>     INTEGER
  53. %token  <f>     FLOAT
  54. %token  <c>     CHARACTER
  55. %token  <s>     STRING
  56. %type   <i>     header
  57. %type   <s>     class
  58. %type   <i>     variables0
  59. %type   <i>     pointers0
  60. %type   <i>     pointers
  61. %type   <i>     metas0
  62. %type   <i>     metas
  63. %type   <i>     args0
  64. %type   <i>     args
  65. %type   <i>     literal
  66. %type   <i>     integer
  67. %type   <i>     float
  68. %type   <i>     indices
  69. %type   <i>     location
  70. %type   <i>     accessors
  71. %type   <i>     l1
  72. %type   <i>     l2
  73. %type   <i>     l3
  74. %type   <i>     l4
  75. %type   <i>     l1_
  76. %type   <i>     l2_
  77. %type   <i>     l3_
  78. %%
  79. start           : DO                                            { emit0 (".text");
  80.                                                                   entry ("main"); }
  81.                   main                                          {}
  82.                 | programs                                      {}
  83.                 ;
  84. programs        : programs program                              {}
  85.                 | program                                       {}
  86.                 ;
  87. program         : header ':' INTEGER ':' INTEGER                { pix = put(pname, $1, $5);
  88.                                                                   emit0 (".data");
  89.                                                                   emit0 (".align");
  90.                                                                   labelC(pix);
  91.                                                                   if (isupper(*pname)) {
  92.                                                                       emit0c(".word", 1);
  93.                                                                       emit0c(".word", 2);
  94.                                                                       emit0c(".word", 3);
  95.                                                                   }}
  96.                   genes0 '{' data0 '}'                          { emit0 (".text"); }
  97.                   '{' goal0 procedures0 '}'                     { pix = 0; }
  98.                 ;
  99. header          : CID ISA CID                                   { pname = $3; $$ = get($1); }
  100.                 | ID  ISA ID                                    { pname = $3; $$ = get($1); }
  101.                 | CID                                           { pname = $1; $$ = 0; }
  102.                 | ID                                            { pname = $1; $$ = 0; }
  103.                 ;
  104. genes0          : LT genes GT                                   {}
  105.                 | empty                                         {}
  106.                 ;
  107. genes           : genes ',' gene                                {}
  108.                 | gene                                          {}
  109.                 ;
  110. gene            : GID                                           { emit0c(".word", $1); }
  111.                 ;
  112. data0           : atoms0 ';'                                    { emit0c(".word", -1); }
  113.                   molecules0 ';'                                { emit0c(".word", -1); }
  114.                   polymorphs0                                   { emit0c(".word", -1); }
  115.                 ;
  116. atoms0          : atoms                                         {}
  117.                 | empty                                         {}
  118.                 ;
  119. atoms           : atoms ',' atom                                {}
  120.                 | atom                                          {}
  121.                 ;
  122. atom            : GID w                                         { emit0c(".word", $1); }
  123.                 ;
  124. molecules0      : molecules                                     {}
  125.                 | empty                                         {}
  126.                 ;
  127. molecules       : molecules ',' molecule                        {}
  128.                 | molecule                                      {}
  129.                 ;
  130. molecule        : GID p                                         { emit0c(".word", $1); }
  131.                 ;
  132. polymorphs0     : polymorphs                                    {}
  133.                 | empty                                         {}
  134.                 ;
  135. polymorphs      : polymorphs ',' polymorph                      {}
  136.                 | polymorph                                     {}
  137.                 ;
  138. polymorph       : GID G                                         { emit0c(".word", $1);
  139.                                                                   emit0c(".word", $2); }
  140.                 ;
  141. goal0           : goal                                          {}
  142.                 | empty                                         {}
  143.                 ;
  144. goal            : DO                                            { labelL(pix, 0);
  145.                                                                   fill  (pix, 0); }
  146.                   main                                          {}
  147.                 ;
  148. main            : INTEGER                                       { skip = fail = gen(1);
  149.                                                                   failed = FALSE;
  150.                                                                   emit2 ("entr", k = 1, s = $1+1); }
  151.                   body '.'                                      { emit0 ("done");
  152.                                                                   emit1 ("exit", s);
  153.                                                                   if (failed) {
  154.                                                                       label (fail);
  155.                                                                       emit0 ("quit");
  156.                                                                       emit1 ("exit", s);
  157.                                                                   }}
  158.                 ;
  159. procedures0     : procedures                                    {}
  160.                 | empty                                         {}
  161.                 ;
  162. procedures      : procedures procedure                          {}
  163.                 | procedure                                     {}
  164.                 ;
  165. procedure       : rules '.'                                     { if (failed) {
  166.                                                                       label (fail);
  167.                                                                       emit2 ("fail", k, s);
  168.                                                                   }}
  169.                 ;
  170. rules           : rules ';'                                     { label (next); }
  171.                   mark0 rule                                    {}
  172.                 | prolog check0 mark0 rule                      {}
  173.                 ;
  174. prolog          : MID ':' INTEGER ':' INTEGER ':' INTEGER       { labelL(pix, $1);
  175.                                                                   fill  (pix, $1);
  176.                                                                   fail = gen(1);
  177.                                                                   failed = FALSE;
  178.                                                                   k = $3 < $5 ? $5+1 : $3+1;
  179.                                                                   emit2 ("entr", k, s = $7+1); }
  180.                 ;
  181. check0          :                                               { emit0_("chek", skip = gen(1));
  182.                                                                   emit0_("coll", gen(1));
  183.                                                                   emit0 (".data");
  184.                                                                   label (gen(0)); }
  185.                   '[' variables0 ']'                            { emit0 (".text");
  186.                                                                   label (skip); }
  187.                 | empty                                         {}
  188.                 ;
  189. mark0           : ';'                                           { skip = next = fail; }
  190.                 | empty                                         { skip = next = gen(1); }
  191.                 ;
  192. rule            :                                               { a = s; n = 0; }
  193.                   '(' inputs0 ')' clause0 RETURN result0        {}
  194.                 ;
  195. clause0         : IF   body then body                           {}
  196.                 | IF   body                                     {}
  197.                 | then body                                     {}
  198.                 | empty                                         {}
  199.                 ;
  200. then            : THEN                                          { skip = fail; }
  201.                 ;
  202. body            : body ';' messages                             {}
  203.                 | messages                                      {}
  204.                 ;
  205. messages        : mess ',' messages sage                        { failed = memo(skip, fail); }
  206.                 | mess sage                                     { failed = memo(skip, fail); }
  207.                 | message                                       { failed = memo(skip, fail); }
  208.                 | primitive                                     {}
  209.                 ;
  210. mess            : MID '[' args0 ']' '(' parameters0 ')'
  211.                       '[' args0 ']'                             { emit1c("lodc", ++n, $9);
  212.                                                                   emit1c("lodc", ++n, $3);
  213.                                                                   emit1c("lodc", ++n, $1); }
  214.                   '!' remote                                    { emit1 ("send", n); }
  215.                 ;
  216. sage            : ':' INTEGER                                   { emit1_("recv", n = $2, skip); }
  217.                   '(' outputs0 ')'                              {}
  218.                 ;
  219. message         : MID ':' INTEGER ':' INTEGER                   { n = $3 < $5 ? $5-$3 : 0; }
  220.                   '(' parameters0 ')' target                    { emit0_(".addr", gen(1));
  221.                                                                   emit0_(".addr", skip); }
  222.                   '[' variables0 ']'                            { label (gen(0));
  223.                                                                   n = $5; }
  224.                   '(' outputs0 ')'                              {}
  225.                 ;
  226. target          : '!' local                                     { emit3 ("invk", n, $<i>-4, $<i>-8); }
  227.                 | class                                         { emit2 ("lods", ++n, s);
  228.                                                                   emit2L("call", n, $<i>-4, Lab($1, $<i>-8)); }
  229.                 ;
  230. result0         : MID '(' parameters0 ')' class                 { emit3L("jump", k, s, n, Lab($5, $1)); }
  231.                 | check0 '(' parameters0 ')'                    { emit3 ("retr", k, s, n); }
  232.                 | check0 '(' parameters0 ')' '*'                { emit3 ("rets", k, s, n); }
  233.                 | empty                                         {}
  234.                 ;
  235. remote          : location A                                    { emit3 ("lodm", n, n, $1); }
  236.                 | LID A                                         { emit2 ("lods", ++n, s+$1); }
  237.                 | handle                                        {}
  238.                 ;
  239. local           : location O                                    { emit3 ("lodm", n, n, $1); }
  240.                 | LID O                                         { emit2 ("lods", ++n, s+$1); }
  241.                 ;
  242. class           : ISA CID                                       { $$ = $2; }
  243.                 | ISA ID                                        { $$ = $2; }
  244.                 | empty                                         { $$ = pname; }
  245.                 ;
  246. primitive       : equality                                      { failed = memo(skip, fail); }
  247.                 | inequality                                    { failed = memo(skip, fail); }
  248.                 | matching                                      {}
  249.                 | synchrony                                     {}
  250.                 | TRUE                                          {}
  251.                 | FAIL                                          { emit0_("bran", skip);
  252.                                                                   failed = memo(skip, fail); }
  253.                 ;
  254. equality        : parameter EQ expression                       { emit2_("bner", n-1, n,     skip); n-=2; }
  255.                 | parameter NE expression                       { emit2_("beqr", n-1, n,     skip); n-=2; }
  256.                 | parameter EQ location x                       { emit3_("bnem", n-1, n, $3, skip); n-=2; }
  257.                 | parameter NE location x                       { emit3_("beqm", n-1, n, $3, skip); n-=2; }
  258.                 | parameter EQ LID x                            { emit2_("bnes", n--, s+$3,  skip); }
  259.                 | parameter NE LID x                            { emit2_("beqs", n--, s+$3,  skip); }
  260.                 | parameter EQ nil                              { emit1_("bnez", n--,        skip); }
  261.                 | parameter NE nil                              { emit1_("beqz", n--,        skip); }
  262.                 | parameter EQ literal                          { if ($3) emitc_("bnec", n--, $3, skip);
  263.                                                                   else    emit1_("bnez", n--,     skip); }
  264.                 | parameter NE literal                          { if ($3) emitc_("beqc", n--, $3, skip);
  265.                                                                   else    emit1_("beqz", n--,     skip); }
  266.                 ;
  267. inequality      : express I LT express I                        { emit1_("bge.i", n--, skip); n--; }
  268.                 | express I LE express I                        { emit1_("bgt.i", n--, skip); n--; }
  269.                 | express I GT express I                        { emit1_("ble.i", n--, skip); n--; }
  270.                 | express I GE express I                        { emit1_("blt.i", n--, skip); n--; }
  271.                 | express F LT express F                        { emit1_("bge.f", n--, skip); n--; }
  272.                 | express F LE express F                        { emit1_("bgt.f", n--, skip); n--; }
  273.                 | express F GT express F                        { emit1_("ble.f", n--, skip); n--; }
  274.                 | express F GE express F                        { emit1_("blt.f", n--, skip); n--; }
  275.                 ;
  276. matching        : parameter '=' pattern0_as                     { n--; }
  277.                 | parameter '=' '_'                             { n--; }
  278.                 ;
  279. synchrony       : POST '(' parameter ')' '!' VID                { emit2 ("post", n--, $6); }
  280.                 | WAIT '(' parameter ')' '!' VID                { emit2_("wait", n--, $6, gen(1)); }
  281.                   '[' variables0 ']'                            { emit0c(".word", $9 + 3);
  282.                                                                   label (gen(0)); }
  283.                 ;
  284. variables0      : pointers0 ';'                                 { emit0c(".word", -s); }
  285.                   metas0                                        { emit0c(".word", -s-k);
  286.                                                                   $$ = $1 + $4; }
  287.                 ;
  288. pointers0       : pointers                                      { $$ = $1; }
  289.                 | empty                                         { $$ = 0; }
  290.                 ;
  291. pointers        : pointers ',' pointer                          { $$ = $1 + 1; }
  292.                 | pointer                                       { $$ = 1; }
  293.                 ;
  294. pointer         : LID p                                         { emit0c(".word", s+$1); }
  295.                 ;
  296. metas0          : metas                                         { $$ = $1; }
  297.                 | empty                                         { $$ = 0; }
  298.                 ;
  299. metas           : metas ',' meta                                { $$ = $1 + 2; }
  300.                 | meta                                          { $$ = 2; }
  301.                 ;
  302. meta            : LID G                                         { emit0c(".word", s+$1);
  303.                                                                   emit0c(".word", $2); }
  304.                 ;
  305. x               : w                                             {}
  306.                 | p                                             {}
  307.                 | G                                             {}
  308.                 ;
  309. w               : C                                             {}
  310.                 | I                                             {}
  311.                 | F                                             {}
  312.                 ;
  313. p               : O                                             {}
  314.                 | A                                             {}
  315.                 | Y                                             {}
  316.                 | L                                             {}
  317.                 ;
  318. args0           : args                                          { $$ = $1; }
  319.                 | empty                                         { $$ = 0; }
  320.                 ;
  321. args            : args ',' arg                                  { $$ = $1 + 1; }
  322.                 | arg                                           { $$ = 1; }
  323.                 ;
  324. arg             : C                                             { emit1c("lodc", ++n, T_CHAR);    }
  325.                 | I                                             { emit1c("lodc", ++n, T_INT);     }
  326.                 | F                                             { emit1c("lodc", ++n, T_FLOAT);   }
  327.                 | p                                             { emit1c("lodc", ++n, T_POINTER); }
  328.                 | G                                             { emit2 ("lods", ++n, s);
  329.                                                                   emit3 ("lodm", n, n, $1);  }
  330.                 ;
  331. parameters0     : parameters                                    {}
  332.                 | empty                                         {}
  333.                 ;
  334. parameters      : parameters ',' parameter                      {}
  335.                 | parameter                                     {}
  336.                 ;
  337. parameter       : instance                                      {}
  338.                 | expression                                    {}
  339.                 | location x                                    { emit3 ("lodm", n, n, $1); }
  340.                 | LID x                                         { emit2 ("lods", ++n, s+$1); }
  341.                 | nil                                           { emit1 ("lodz", ++n); }
  342.                 | literal                                       { if ($1) emit1c("lodc", ++n, $1);
  343.                                                                   else    emit1 ("lodz", ++n); }
  344.                 ;
  345. value           : instance                                      { emit3 ("stor", n-1, ++b, n);     n--; }
  346.                 | expression                                    { emit3 ("stor", n-1, ++b, n);     n--; }
  347.                 | location x                                    { emit4 ("stom", n-1, ++b, n, $1); n--; }
  348.                 | LID x                                         { emit3 ("stos", n,   ++b, s+$1); }
  349.                 | nil                                           { emit2 ("stoz", n,   ++b); }
  350.                 | literal                                       { if ($1) emit2c("stoc", n, ++b, $1);
  351.                                                                   else    emit2 ("stoz", n, ++b); }
  352.                 ;
  353. instance        : list                                          {}
  354.                 | array                                         {}
  355.                 | string                                        {}
  356.                 | handle                                        {}
  357.                 | agent                                         {}
  358.                 | object                                        {}
  359.                 ;
  360. list            : l2 elements '|' location L ']'                { emit4 ("stom", n-1, ++b, n, $4); b = $1; n--; }
  361.                 | l2 elements '|' LID L ']'                     { emit3 ("stos", n,   ++b, s+$4);  b = $1; }
  362.                 | l2 elements ']'                               { emit2 ("stoz", n,   ++b);        b = $1; }
  363.                 ;
  364. l2              : INTEGER                                       { emit2 ("brek", ++n, $1*3); }
  365.                   elem_t '['                                    { $$ = b; b = 0; }
  366.                 ;
  367. elem_t          : C                                             { emit2c("stoc", n, 0, HEADER(I_LISTC, 3)); }
  368.                 | I                                             { emit2c("stoc", n, 0, HEADER(I_LISTI, 3)); }
  369.                 | F                                             { emit2c("stoc", n, 0, HEADER(I_LISTF, 3)); }
  370.                 | p                                             { emit2c("stoc", n, 0, HEADER(I_LISTP, 3)); }
  371.                 | G                                             { emit2 ("lods", n+1, s);
  372.                                                                   emit4 ("stom", n, 0, n+1, $1); }
  373.                 ;
  374. elements        : elements ','                                  { emit2 ("cdra", n, ++b);
  375.                                                                   emit4 ("stom", n, ++b, n, 0); }
  376.                   element                                       {}
  377.                 | element                                       {}
  378.                 ;
  379. element         : value                                         {}
  380.                 ;
  381. array           : l3 '[' sizes ']' '{' items '}'                { b = $1; }
  382.                 | l3 '[' sizes ']'                              { b = $1; }
  383.                 ;
  384. string          : STRING                                        { int i, j = strlen($1);
  385.                                                                   emit2 ("brek", ++n,  3+j);
  386.                                                                   emit2c("stoc", n, 0, HEADER(I_ARRAYC, 3+j));
  387.                                                                   emit2c("stoc", n, 1, 1);
  388.                                                                   if (j) emit2c("stoc", n, 2, j);
  389.                                                                   else   emit2 ("stoz", n, 2);
  390.                                                                   for (i = 0; i < j; i++)
  391.                                                                       emit2c("stoc", n, i+3, $1[i]); }
  392.                 ;
  393. l3              : INTEGER ':' INTEGER                           { emit2 ("brek", ++n,  2+$1+$3);
  394.                                                                   emit2 ("zero", n,    2+$1+$3);
  395.                                                                   $<i>$ = 2+$1+$3; }
  396.                   item_t '$'                                    { emit2c("stoc", n, 1, $1);
  397.                                                                   $$ = b; b = 1; }
  398.                 ;
  399. item_t          : C                                             { emit2c("stoc", n, 0, HEADER(I_ARRAYC, $<i>0)); }
  400.                 | I                                             { emit2c("stoc", n, 0, HEADER(I_ARRAYI, $<i>0)); }
  401.                 | F                                             { emit2c("stoc", n, 0, HEADER(I_ARRAYF, $<i>0)); }
  402.                 | p                                             { emit2c("stoc", n, 0, HEADER(I_ARRAYP, $<i>0)); }
  403.                 | G                                             { emit2 ("lods",   n+1, s);
  404.                                                                   emit3 ("lodm.i", n+1, n+1, $1);
  405.                                                                   emit1c("lodc.i", n+2, OFFSET($<i>0));
  406.                                                                   emit1 ("add.i",  n+2);
  407.                                                                   emit1 ("itow",   n+1);
  408.                                                                   emit3 ("stor",   n, 0, n+1); }
  409.                 ;
  410. sizes           : sizes ',' size                                {}
  411.                 | size                                          {}
  412.                 ;
  413. size            : value                                         {}
  414.                 ;
  415. items           : items ',' item                                {}
  416.                 | item                                          {}
  417.                 ;
  418. item            : value                                         {}
  419.                 ;
  420. handle          : CID ':' INTEGER ATINET ':' INTEGER            { emit2 ("brek", ++n, 4);
  421.                                                                   emit2c("stoc", n, 0, HEADER(I_HANDLE, 4));
  422.                                                                   emit2c("stoc", n, 1, HEADER(get($1), $3));
  423.                                                                   if ($4) emit2c("stoc", n, 2, $4);
  424.                                                                   else    emit2 ("stoz", n, 2);
  425.                                                                   if ($6) emit2c("stoc", n, 3, $6);
  426.                                                                   else    emit2 ("stoz", n, 3); }
  427.                 ;
  428. agent           : l4 types0 '{' properties0 '}'
  429.                   ATINET ':' INTEGER                            { if ($6) emit2c("stoc", n, 2, $6);
  430.                                                                   else    emit2 ("stoz", n, 2);
  431.                                                                   if ($8) emit2c("stoc", n, 3, $8);
  432.                                                                   else    emit2 ("stoz", n, 3);
  433.                                                                   emit1 ("cret", n);
  434.                                                                   b = $1; }
  435.                 ;
  436. l4              : CID ':' INTEGER                               { emit2 ("brek", ++n, $3);
  437.                                                                   emit2c("stoc", n, 0, HEADER(get($1), $3));
  438.                                                                   emit2c("stoc", n, 1, HEADER(get($1), $3));
  439.                                                                   $$ = b; b = 3; }
  440.                 ;
  441. object          : l1 types0 '{' properties0 '}'                 { b = $1; }
  442.                 ;
  443. l1              : ID ':' INTEGER                                { emit2 ("brek", ++n, $3);
  444.                                                                   emit2c("stoc", n, 0, HEADER(get($1), $3));
  445.                                                                   $$ = b; b = 0; }
  446.                 ;
  447. types0          : '[' types ']'                                 {}
  448.                 | empty                                         {}
  449.                 ;
  450. types           : types ',' type                                {}
  451.                 | type                                          {}
  452.                 ;
  453. type            : C                                             { emit2c("stoc", n, ++b, T_CHAR);    }
  454.                 | I                                             { emit2c("stoc", n, ++b, T_INT);     }
  455.                 | F                                             { emit2c("stoc", n, ++b, T_FLOAT);   }
  456.                 | p                                             { emit2c("stoc", n, ++b, T_POINTER); }
  457.                 | G                                             { emit2 ("lods", n+1, s);
  458.                                                                   emit4 ("stom", n, ++b, n+1, $1);  }
  459.                 ;
  460. properties0     : properties                                    {}
  461.                 | empty                                         {}
  462.                 ;
  463. properties      : properties ',' property                       {}
  464.                 | property                                      {}
  465.                 ;
  466. property        : value                                         {}
  467.                 ;
  468. location        : GID                                           { emit2 ("lods", ++n, s);
  469.                                                                   emit3 ("lodm", n, n, $1); }
  470.                   accessors                                     { $$ = $3; }
  471.                 | LID                                           { emit2 ("lods", ++n, s+$1); }
  472.                   accessors                                     { $$ = $3; }
  473.                 | GID                                           { emit2 ("lods", ++n, s);
  474.                                                                   $$ = $1; }
  475.                 ;
  476. accessors       : accessor accessors                            { $$ = $2; }
  477.                 | DOT GID                                       { $$ = $2; }
  478.                 | '[' indices ']'                               { $$ = $2+2;
  479.                                                                   emit1 ("indx", n--); }
  480.                 ;
  481. accessor        : DOT GID                                       { emit3 ("lodm", n, n, $2); }
  482.                 | '[' indices ']'                               { emit1 ("indx", n--);
  483.                                                                   emit3 ("lodm", n, n, $2+2); }
  484.                 ;
  485. indices         : indices ','                                   { emit3 ("lodm.i", n+1, n-1, $1+2);
  486.                                                                   emit1 ("mul.i", n+1); }
  487.                   index                                         { emit1 ("add.i", n--);
  488.                                                                   $$ = $1 + 1; }
  489.                 | index                                         { $$ = 1; }
  490.                 ;
  491. index           : express I                                     {}
  492.                 ;
  493. expression      : express I                                     { emit1 ("itow", n); }
  494.                 | express F                                     { emit1 ("ftow", n); }
  495.                 ;
  496. express         : '(' expr ')'                                  {}
  497.                 ;
  498. expr            : expr '-' '\'' F term                          { emit1 ("subr.f", n--); }
  499.                 | expr '-' '\'' I term                          { emit1 ("subr.i", n--); }
  500.                 | expr '+' F term                               { emit1 ("add.f",  n--); }
  501.                 | expr '-' F term                               { emit1 ("sub.f",  n--); }
  502.                 | expr '+' I term                               { emit1 ("add.i",  n--); }
  503.                 | expr '-' I term                               { emit1 ("sub.i",  n--); }
  504.                 | '-' F factor                                  { emit1 ("neg.f",  n); }
  505.                 | '-' I factor                                  { emit1 ("neg.i",  n); }
  506.                 | term                                          {}
  507.                 ;
  508. term            : term '/' '\'' F factor                        { emit1 ("divr.f", n--); }
  509.                 | term '%' '\'' F factor                        { emit1 ("remr.f", n--); }
  510.                 | term '/' '\'' I factor                        { emit1 ("divr.i", n--); }
  511.                 | term '%' '\'' I factor                        { emit1 ("remr.i", n--); }
  512.                 | term '*' F factor                             { emit1 ("mul.f",  n--); }
  513.                 | term '/' F factor                             { emit1 ("div.f",  n--); }
  514.                 | term '%' F factor                             { emit1 ("rem.f",  n--); }
  515.                 | term '*' I factor                             { emit1 ("mul.i",  n--); }
  516.                 | term '/' I factor                             { emit1 ("div.i",  n--); }
  517.                 | term '%' I factor                             { emit1 ("rem.i",  n--); }
  518.                 | factor                                        {}
  519.                 ;
  520. factor          : express                                       {}
  521.                 | ID express                                    { emit1 ($1, n); }
  522.                 | location I                                    { emit3 ("lodm.i",   n, n, $1); }
  523.                 | location F                                    { emit3 ("lodm.f",   n, n, $1); }
  524.                 | LID I                                         { emit2 ("lods.i", ++n, s+$1); }
  525.                 | LID F                                         { emit2 ("lods.f", ++n, s+$1); }
  526.                 | integer                                       { if ($1) emit1c("lodc.i", ++n, $1);
  527.                                                                   else    emit1 ("lodz.i", ++n); }
  528.                 | float                                         { if ($1) emit1c("lodc.f", ++n, $1);
  529.                                                                   else    emit1 ("lodz.f", ++n); }
  530.                 ;
  531. literal         : integer                                       { $$ = $1; }
  532.                 | float                                         { $$ = $1; }
  533.                 | CHARACTER                                     { $$ = $1; }
  534.                 ;
  535. integer         : '-' INTEGER                                   { $$ = -$2; }
  536.                 | INTEGER                                       { $$ = $1; }
  537.                 ;
  538. float           : '-' FLOAT                                     { $$ = ftow(-$2); }
  539.                 | FLOAT                                         { $$ = ftow($1); }
  540.                 ;
  541. nil             : NIL                                           {}
  542.                 | '[' ']'                                       {}
  543.                 ;
  544. outputs0        : outputs                                       {}
  545.                 | empty                                         {}
  546.                 ;
  547. outputs         : outputs ',' output                            {}
  548.                 | output                                        {}
  549.                 ;
  550. output          : pattern0_as                                   { n--; }
  551.                 | '_'                                           { n--; }
  552.                 ;
  553. inputs0         : inputs                                        {}
  554.                 | empty                                         {}
  555.                 ;
  556. inputs          : inputs ',' input                              {}
  557.                 | input                                         {}
  558.                 ;
  559. input           :                                               { emit2 ("lods", ++n, ++a); }
  560.                   pattern0_as                                   { n--; }
  561.                 | '_'                                           { ++a; }
  562.                 ;
  563. value_          :                                               { emit3 ("lodm", n+1, n, ++a); ++n; }
  564.                   pattern0_as                                   { n--; }
  565.                 | '_'                                           { ++a; }
  566.                 ;
  567. pattern0_as     : pattern0_ '?' location x                      { emit3 ("stor", n, $3, n-1); n--; }
  568.                 | pattern0_ '?' LID x                           { emit2 ("move", n, s+$3); }
  569.                 | pattern_                                      { failed = memo(skip, fail); }
  570.                 ;
  571. pattern0_       : pattern_                                      { failed = memo(skip, fail); }
  572.                 | empty                                         {}
  573.                 ;
  574. pattern_        : instance_                                     {}
  575.                 | expression_                                   {}
  576.                 | reference_                                    {}
  577.                 | literal_                                      {}
  578.                 | nil_                                          {}
  579.                 ;
  580. instance_       : list_                                         {}
  581.                 | array_                                        {}
  582.                 | string_                                       {}
  583.                 | handle_                                       {}
  584.                 | object_                                       {}
  585.                 ;
  586. list_           : l2_ elements_ '|'                             { a = 1; }
  587.                   value_ ']'                                    { a = $1; n--; }
  588.                 | l2_ elements_ ']'                             { emit3 ("lodm", n, n, ++a); a = $1;
  589.                                                                   emit1_("bnez", n--, skip); }
  590.                 ;
  591. l2_             : '['                                           { emit1_("beqz", n, skip);
  592.                                                                   emit2 ("lodr", n+1, n);
  593.                                                                   $$ = a; a = 0; ++n; }
  594.                 ;
  595. elements_       : elements_ ','                                 { emit3 ("lodm", n, n, ++a); a = 0;
  596.                                                                   emit1_("beqz", n, skip); }
  597.                   element_                                      {}
  598.                 | element_                                      {}
  599.                 ;
  600. element_        : value_                                        {}
  601.                 ;
  602. array_          : l3_ '[' sizes_ ']' '{' items_ '}'             { a = $1; }
  603.                 | l3_ '[' sizes_ ']'                            { a = $1; }
  604.                 ;
  605. string_         : STRING                                        { int i, j = strlen($1);
  606.                                                                   emit1_("beqz", n, skip);
  607.                                                                   emit3 ("lodm", n+1, n, 2);
  608.                                                                   if (j) emitc_("bnec", n+1, j, skip);
  609.                                                                   else   emit1_("bnez", n+1,    skip);
  610.                                                                   for (i = 0; i < j; i++) {
  611.                                                                       emit3 ("lodm", n+1, n, i+3);
  612.                                                                       emitc_("bnec", n+1, $1[i], skip);
  613.                                                                   }}
  614.                 ;
  615. l3_             : '$'                                           { emit1_("beqz", n, skip);
  616.                                                                   $$ = a; a = 1; }
  617.                 ;
  618. sizes_          : sizes_ ',' size_                              {}
  619.                 | size_                                         {}
  620.                 ;
  621. size_           : value_                                        {}
  622.                 ;
  623. items_          : items_ ',' item_                              {}
  624.                 | item_                                         {}
  625.                 ;
  626. item_           : value_                                        {}
  627.                 ;
  628. handle_         : CID ':' INTEGER ATINET ':' INTEGER            { emit1_("beqz", n, skip);
  629.                                                                   emit3 ("lodm", n+1, n, 1);
  630.                                                                   emitc_("bnec", n+1, HEADER(get($1), $3), skip);
  631.                                                                   emit3 ("lodm", n+1, n, 2);
  632.                                                                   if ($4) emitc_("bnec", n+1, $4, skip);
  633.                                                                   else    emit1_("bnez", n+1,     skip);
  634.                                                                   emit3 ("lodm", n+1, n, 3);
  635.                                                                   if ($6) emitc_("bnec", n+1, $6, skip);
  636.                                                                   else    emit1_("bnez", n+1,     skip); }
  637.                 ;
  638. object_         : l1_ types0_ '{' properties0_ '}'              { a = $1; }
  639.                 ;
  640. l1_             : ID ':' INTEGER                                { emit1_("beqz", n, skip);
  641.                                                                   emit3 ("lodm", n+1, n, 0);
  642.                                                                   emitc_("bnec", n+1, HEADER(get($1), $3), skip);
  643.                                                                   $$ = a; a = 0; }
  644.                 ;
  645. types0_         : '[' types_ ']'                                {}
  646.                 | empty                                         {}
  647.                 ;
  648. types_          : types_ ',' type_                              {}
  649.                 | type_                                         {}
  650.                 ;
  651. type_           : x                                             { ++a; }
  652.                 ;
  653. properties0_    : properties_                                   {}
  654.                 | empty                                         {}
  655.                 ;
  656. properties_     : properties_ ',' property_                     {}
  657.                 | property_                                     {}
  658.                 ;
  659. property_       : value_                                        {}
  660.                 ;
  661. expression_     : expression                                    { emit2_("bner", n-1, n,     skip); n--; }
  662.                 ;
  663. reference_      : location x                                    { emit3_("bnem", n-1, n, $1, skip); n--; }
  664.                 | LID x                                         { emit2_("bnes", n,    s+$1, skip); }
  665.                 ;
  666. literal_        : literal                                       { if ($1) emitc_("bnec", n, $1, skip);
  667.                                                                   else    emit1_("bnez", n,     skip); }
  668.                 ;
  669. nil_            : nil                                           { emit1_("bnez", n, skip); }
  670.                 ;
  671. empty           :                                               {}
  672.                 ;
  673. %%
  674. int     get(id)
  675. char   *id;
  676. {
  677.         int     i;
  678.  
  679.         for (i = 0; i < pno; i++)
  680.             if (!strcmp(ptab[i].name, id))
  681.                 return i;
  682. #ifdef  SHELL
  683.         err1("Unimplemented class `%s'.\n", id);
  684.         exit(0);
  685. #endif
  686.         ptab[pno].name = new(id);
  687.         ptab[pno].isa  = 0;
  688.         ptab[pno].mno  = -1;
  689.         ptab[pno].mtab = NUL;
  690.         return pno++;
  691. }
  692.  
  693. int     put(id, isa, mno)
  694. char   *id;
  695. int     isa;
  696. int     mno;
  697. {
  698.         int     i = get(id);
  699.     
  700.         if (ptab[i].mno == -1) {
  701.             ptab[i].mno  = mno;
  702.             ptab[i].isa  = isa;
  703.             ptab[i].mtab = newz(mno);
  704.             return i;
  705.         }
  706.         if (ptab[i].mno > 1) {
  707.             err1("Duplicate program `%s' ignored.\n", id);
  708.             return -1;
  709.         }
  710.         return -1;
  711. }
  712.  
  713. void    fill(i, j)
  714. int     i;
  715. int     j;
  716. {
  717.         if (i != -1) ptab[i].mtab[j] = i;
  718. }
  719.  
  720. void    init_gen(sno, stab)
  721. int     sno;
  722. char   *stab[];
  723. {
  724.         int     i;
  725.  
  726.         ptab = (Program *) calloc(PNO, sizeof(Program));
  727.         for (i = 0; i < sno; i++)
  728.             put(stab[i], 0, 0);
  729. }
  730.  
  731. void    generate(pbuf, tbuf)
  732. char   *pbuf;
  733. char   *tbuf;
  734. {
  735.         buf = tbuf;
  736.         init_scan(pbuf);
  737.         zzparse();
  738. }
  739.  
  740.